/*
 * @Author: 梓岄 3049738225@qq.com
 * @Date: 2025-11-28 18:21:28
 * @LastEditors: 梓岄 3049738225@qq.com
 * @LastEditTime: 2025-11-28 20:14:38
 * @FilePath: /fifo/Fifo.hpp
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
#include <iostream>
#include <cstdio>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string>
#include <cstring>

#define MODE 0666

#define ForRead 1
#define ForWrite 2

const char *gcommfile = "./fifo";

class Myfifo
{
public:
    Myfifo(const char *commfile = gcommfile, mode_t mode = MODE)
        : _commfile(commfile), _mode(mode), _fd(-1)
    {
    }

    void Creat()
    {
        int rt = mkfifo(_commfile, _mode);
        if (rt < 0)
        {
            std::cerr << "mkfifo error" << std::endl;
            exit(1);
        }
    }

    void Open(int openmode)
    {
        if (!IsExists())
        {
            std::cout << "Fifo is not exists!" << std::endl;
            exit(4);
        }
        if (openmode == ForRead)
        {
            _fd = open(_commfile, O_RDONLY);
        }
        else if (openmode == ForWrite)
        {
            _fd = open(_commfile, O_WRONLY);
        }
        else
        {
            std::cerr << "openmode error" << std::endl;
            exit(3);
        }
        if (_fd < 0)
        {
            std::cerr << "open error" << std::endl;
            exit(2);
        }
    }

    void Send(const std::string &str)
    {
        ssize_t n = write(_fd, str.c_str(), str.size());
        (void)n;
    }

    int Rcev(std::string &str)
    {
        char ch[128];

        int n = read(_fd, ch, sizeof(ch) - 1);
        if (n > 0)
        {
            ch[n] = 0;
            str = ch;
            return str.size();
        }
        else if (n == 0)
        {
            return 0;
        }
        else
        {
            return -1;
        }
    }

    int Delet()
    {
        int n = -1;
        if (IsExists())
        {
            n = unlink(_commfile);
            close(_fd);
        }
        return n;
    }

    ~Myfifo() {}

private:

    bool IsExists()
    {
        struct stat st;
        int n = stat(_commfile, &st);
        if (n == 0)
        {
            return true;
        }
        else
        {
            errno = 0;
            return false;
        }
    }

private:
    const char *_commfile;
    mode_t _mode;
    int _fd;
};
